package cn.jsj.hzu.qm.facecloud.pyAi;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.List;

//import cn.hzxy.jsj.cxsys.asrc.lac.jserver.Service.OutPutStreamManager;

/***
 * 用于直接操作LAC的类
 * <br> <b>工作流程：</b><br>
 * <ol>
 * <li>通过 LACConnector 获取此对象</li>
 * <li>使用 setInString 设置输入</li>
 * <li>使用 setStateToRun 设置状态码为可执行状态<b>注：潜在的设置失败，注意判断</b></li>
 * <li>使用 getState 获取当前进程的状态。如果为 STATE_OUT_READY，说明执行完毕</li>
 * <li>使用 getOutString 获取当前就绪的输出</li>
 * <li>使用 LACConnector 对象的 free 方法归还此LAC对象</li>
 * </ol>
 * 
 * */
public class LACObject {
	/**
	 * 状态码：未分配
	 */
	public static final String STATE_FREE = "STATE_FREE.state";
	
	/**
	 * 状态码：空状态
	 */
	public static final String STATE_0 = "STATE_0.state";

	/**
	 * 状态码：输入就绪
	 */
	public static final String STATE_IN_READY = "STATE_IN_READY.state";

	/**
	 * 状态码：正在运行
	 */
	public static final String STATE_RUNNING = "STATE_RUNNING.state";

	/**
	 * 状态码：输出就绪
	 */
	public static final String STATE_OUT_READY  = "STATE_OUT_READY.state";

	/**
	 * 状态码：错误
	 */
	public static final String STATE_ERROR = "STATE_ERROR.state";

	/**
	 * 状态码数组，保存了所有的状态码
	 */
	public static final String STATES[] = { STATE_FREE, STATE_0, STATE_IN_READY, STATE_RUNNING, STATE_OUT_READY, STATE_ERROR };

	/**
	 * 工作目录，即状态码以及输入输出文件所使用的文件夹。
	 * 
	 * <br> 私有属性，由构造方法传入
	 */
	private String work_path;

	/**
	 * 进程对象，保存了LAC_pyServer的进程。
	 * 
	 * <br> 私有属性，由构造方法进行初始化
	 */
	private Process process = null;

	/**
	 * 构造函数，用于指定工作目录
	 * 
	 * @param work_path 工作目录。解释器和原文件的路径在配置文件中定义。
	 */
	public LACObject(String work_path) {
		this.work_path = work_path;
		String runCommandString = "cmd /c start " + FilePropreties.getPythonPathString() + " "
				+ FilePropreties.getRunablePyFileNameString() + " " + work_path+" > "+work_path+File.separator+"runlog.log";
		System.out.println("[exec]: "+runCommandString);
		
		try {
			this.process = Runtime.getRuntime().exec(runCommandString);
//			OutPutStreamManager.addStream(this.process.getInputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取当前进程的状态。
	 * 
	 * @return LACObject.STATES 状态中的一个, 如果发现没有状态，返回错误状态
	 */
	public String getState() {
		File file;
		for (String state : STATES) {
			file = new File(work_path + File.separator + state);
			if (file.isFile()) {
				return state;
			}
		}
		return STATE_ERROR;
	}

	/**
	 * 设置状态 将当前的状态文件设为这个状态
	 */
	public void setState(String stateString) {
		String nowStateString = getState();

		try {
			Process renProcess = Runtime.getRuntime()
					.exec("cmd /c REN " + work_path + File.separator + nowStateString + " " + stateString);
			renProcess.waitFor();
		} catch (IOException | InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 强行终止当前进程（不建议手动调用！）
	 */
	protected void stop() {
		this.process.destroy();
		this.setState(STATE_0);
	}

	
	/**
	 * 设置一个字符串文本输入[已废弃]
	 * <br/>不适用于图像处理
	 * */
	@Deprecated
	public void setInString(String my_str) {
		File file = new File(work_path+File.separator+"str.txt");
		try {
			BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"));
			bufferedWriter.write(my_str);
			bufferedWriter.close();
		
		} catch (IOException e) {
			e.printStackTrace();
		}
		return;
	}
	
	/**
	 * 设置一个图像输入
	 * <br/>适用于图像处理
	 * */
	public void setInJpgImg(List<Integer> imgBytesList) {
		File file = new File(work_path+File.separator+"in.jpg");
		try {
			FileOutputStream outputStream = new FileOutputStream(file);
			for(int i:imgBytesList) {
				outputStream.write(i);
			}
			outputStream.close();
		
		} catch (IOException e) {
			e.printStackTrace();
		}
		return;
	}
	
	
	/**
	 * 设置状态码为可执行状态
	 * @return <ul><li>-1:设置失败，当前程序正在运行</li><li> 0:成功完成</li></ul>
	 * */
	public int setStateToRun() {
		if (getState().equals(STATE_RUNNING)) {
			return -1;
		}
		else {
			setState(STATE_IN_READY);
			return 0;
		}
	}
	
	/**
	 * 获取当前就绪的输出
	 * @return out.json 中的字符串
	 * <br> 如果当前的状态不是 STATE_OUT_READY, 则按格式返回当前的状态字符
	 * */
	public String getOutString() {
		
		String rString = null;
		String nowStateString = getState();
		if (nowStateString.equals(STATE_OUT_READY) == false) {
			rString = "{[\"" + nowStateString + "\"],[\"n\"]}";
		}
		else {
			File file = new File(work_path+File.separator+"out.json");
			try {
				BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file),"utf-8"));//new BufferedReader(new InputStreamReader(new FileInputStream(file), "utf-8") );
				
				rString = bufferedReader.readLine();
				
				bufferedReader.close();//关闭输入
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		return rString;
	}
	/**
	 * 清除工作空间内的所有 STATE 文件，并创建STATE_0.state文件。
	 * */
	public void clearWorkPathState() {
		// TODO Auto-generated method stub

	}
	
	/**
	 * 析构函数 终止进程，并设置状态为零状态
	 */
	@Override
	protected void finalize() throws Throwable {
		this.stop();
	}
	
	protected String getWork_path() {
		return work_path;
	}

}
